/*
 * Epoller.h
 *
 *  Created on: Jul 5, 2024
 *      Author: root
 */

#ifndef BSP_SERVER_EPOLLER_H_
#define BSP_SERVER_EPOLLER_H_
#include "sys/epoll.h"
#include "basic_header.h"

namespace bsp {

class Epoller {
private:
	int fd;
	size_t max_events;
	std::vector<struct epoll_event> que;
	void ctrl(int ops, int fd, uint32_t event);

public:

	Epoller(size_t max_events);

	virtual ~Epoller();

	int open();

	void close() {
	}

	int add(int fd, uint32_t event);

	int del(int fd, uint32_t event);

	int mod(int fd, uint32_t event);

	int wait(int timeout); ///< timeout -1 wait forever,

	struct epoll_event* getEvent(size_t i);

	bool getEvent(size_t wait_result, int fd) {
		bool ret = false;
		for (size_t i = 0; i < wait_result; i++) {
			if (getEvent(i)->data.fd == fd) {
				ret = true;
				break;
			}
		}
		return ret;
	}

	void setSockNonblocking(int fd) {
		const int flag = fcntl(fd, F_GETFL, 0);
		ASSERT(flag > -1, "");
		if (flag & O_NONBLOCK) {

		} else {
			ASSERT(fcntl(fd, F_SETFL, flag | O_NONBLOCK) == 0, "");
		}
	}

	void setSockReuse(int fd) {
		int one = 1;
		ASSERT(setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)) == 0,
				"");
	}

	static void test1();

};

} /* namespace bsp */

#endif /* BSP_SERVER_EPOLLER_H_ */
